package com.polaris.live.dialog

import android.content.Context
import android.view.View
import androidx.annotation.StringRes
import androidx.lifecycle.LifecycleOwner
import com.blankj.utilcode.util.CollectionUtils
import com.blankj.utilcode.util.StringUtils
import com.lxj.xpopup.XPopup
import com.lxj.xpopup.animator.EmptyAnimator
import com.polaris.live.cache.CommonCache
import com.polaris.live.common.manager.CoroutineScopeManager
import com.polaris.live.common.mvvm.viewmodel.BaseViewModel
import com.polaris.live.common.network.manualRequest
import com.polaris.live.common.network.requestLoading
import com.polaris.live.common.network.state.ResultState
import com.polaris.live.common.resp.AppVersionVo
import com.polaris.live.common.util.JsonUtils
import com.polaris.live.common.util.ToastGravity
import com.polaris.live.common.util.ViewUtils
import com.polaris.live.constant.LiveConst
import com.polaris.live.dialog.common.CommonSureDialog
import com.polaris.live.dialog.common.ConfirmDialog
import com.polaris.live.im.sfs.NOTICE_TYPE_TEXT
import com.polaris.live.im.sfs.bean.live.SendLiveNoticeMessage
import com.polaris.live.im.sfs.bean.live.payload.InviteGiftPayloadBean
import com.polaris.live.im.sfs.bean.live.payload.NewAnchorSubsidyPayloadBean
import com.polaris.live.im.sfs.bean.pusher.PopupWindowMessage
import com.polaris.live.net.liveService
import com.polaris.live.net.userService
import com.polaris.live.resp.back_resp.GiftPrivilegePayloadBean
import com.polaris.live.resp.back_resp.PayerRechargeDailyRewardsPriceResp
import com.polaris.live.resp.back_resp.PayerRechargePriceListVo
import com.polaris.live.resp.go_resp.OtherUserIdBean
import com.polaris.live.translation.R.string
import com.polaris.live.utils.XPopupUtils
import com.polaris.live.utils.block.BlockEventMessage
import com.polaris.live.utils.image.ImageUtils
import com.polaris.live.utils.popup_animator.RechargeAnimator
import com.polaris.live.viewmodel.GlobalViewModelProxy
import kotlinx.coroutines.Job
import kotlinx.coroutines.launch
import org.greenrobot.eventbus.EventBus
import java.util.concurrent.ConcurrentHashMap

/**
 * 全局弹窗管理类
 *
 * @author Created by 半仙 on 2023/8/9/009 11:00
 */
object GlobalDialogManager {

    //应用更新
    fun showUpgradeDialog(
        context: Context,
        version: AppVersionVo? = null,
        mainVersionVo: AppVersionVo? = null,
    ) {
        XPopup.Builder(context)
            .dismissOnTouchOutside(false)
            .dismissOnBackPressed(false)
            .isDestroyOnDismiss(true)
            .asCustom(UpgradeDialog(context, version ?: mainVersionVo))
            .show()
    }

    fun showWithdrawTipDialog(context: Context) {
        XPopup.Builder(context)
            .isDestroyOnDismiss(true)
            .asCustom(WithdrawTipDialog(context))
            .show()
    }

    fun showRechargeDialog(
        context: Context,
        todayRechargeResp: List<PayerRechargePriceListVo>,
        onRechargeOk: ((type: Boolean) -> Unit)? = null,
        onCountDown: ((unit: Boolean) -> Unit)? = null,
    ) {
        if (!CollectionUtils.isEmpty(todayRechargeResp)) {
            XPopup.Builder(context)
                .enableDrag(false)
                .dismissOnTouchOutside(false)
                .isDestroyOnDismiss(true)
                .customAnimator(RechargeAnimator())
                .asCustom(
                    TodayGratiaDialog(
                        context,
                        todayRechargeResp,
                        onRechargeOk,
                        onCountDown
                    )
                )
                .show()
        }
    }

    fun showWeekPackPrice(
        viewModel: BaseViewModel,
        onRechargeOk: ((type: Boolean) -> Unit)? = null,
        onHavaWeekPrice: ((Boolean) -> Unit)? = null,
    ) {
        GlobalViewModelProxy.getWeekRecharge(viewModel) { state ->
            if (state is ResultState.Success) {
                val data = state.data
                if (CollectionUtils.isEmpty(data)) {
                    onRechargeOk?.invoke(false)
                    onHavaWeekPrice?.invoke(false)
                    return@getWeekRecharge
                }
                val topActivity = ViewUtils.getAliveTopActivity()
                    ?: return@getWeekRecharge
                XPopup.Builder(topActivity)
                    .enableDrag(false)
                    .dismissOnTouchOutside(false)
                    .isDestroyOnDismiss(true)
                    .asCustom(SevenLimitedTimeDialog(topActivity, state.data, onRechargeOk))
                    .show()
            } else {
                onHavaWeekPrice?.invoke(false)
                onRechargeOk?.invoke(false)
            }
        }
    }

    //拉黑回调      回调后直接赋值即可
    fun showBlackIt(
        context: Context,
        viewModel: BaseViewModel,
        block: Boolean = false,
        nickName: String = "",
        otherId: Long,
        owner: LifecycleOwner? = null,
        blockCallback: (block: Boolean) -> Unit,
    ) {
        if (block) {
            viewModel.requestLoading({ userService.cancelBlack(otherId) }, {
                blockCallback.invoke(false)
                ToastGravity.showGravity(StringUtils.getString(string.un_block))
            }, { ToastGravity.showGravity(it.errorMsg) })
        } else {
            XPopupUtils.showPopup(
                BlockDialog(context, {
                    viewModel.requestLoading(
                        { userService.blockIt(OtherUserIdBean(otherId)) },
                        {
                            blockCallback.invoke(true)
                            EventBus.getDefault().post(BlockEventMessage(otherId))
                            ToastGravity.showGravity(StringUtils.getString(string.block_sucessfully))
                        },
                        { ToastGravity.showGravity(it.errorMsg) })
                }, nickName),
                {
                    hasShadowBg(true)
                },
                lifecycle = owner?.lifecycle
            )
        }
    }

    //关注回调
    fun followOther(
        viewModel: BaseViewModel,
        otherId: Long,
        followed: Boolean,
        followedCallback: (followed: Boolean) -> Unit,
    ) {
        if (followed) {
            viewModel.requestLoading({ userService.deleteFollower(otherId) }, {
                followedCallback.invoke(false)
            }, { ToastGravity.showGravity(it.errorMsg) })
        } else {
            viewModel.requestLoading({ userService.addFollower(OtherUserIdBean(otherId)) }, {
                followedCallback.invoke(true)
                ToastGravity.showGravity(string.follower_succeed)
            }, { ToastGravity.showGravity(it.errorMsg) })
        }
    }

    /**
     * 通用的确认取消弹窗
     */
    fun showConfirmDialog(
        context: Context,
        @StringRes contentId: Int,
        @StringRes confirmTextId: Int? = null,
        @StringRes cancelTextId: Int? = null,
        onCancelClickListener: View.OnClickListener? = null,
        onConfirmClickListener: View.OnClickListener,
    ) {
        showConfirmDialog(
            context,
            StringUtils.getString(contentId),
            confirmTextId?.let { StringUtils.getString(it) },
            cancelTextId?.let { StringUtils.getString(it) },
            onCancelClickListener,
            onConfirmClickListener
        )
    }

    /**
     * 通用的确认取消弹窗
     */
    fun showConfirmDialog(
        context: Context,
        content: String,
        confirmText: String? = null,
        cancelText: String? = null,
        onCancelClickListener: View.OnClickListener? = null,
        onConfirmClickListener: View.OnClickListener,
    ) {
        XPopup.Builder(context)
            .dismissOnTouchOutside(true)
            .dismissOnBackPressed(true)
            .isDestroyOnDismiss(true)
            .asCustom(
                ConfirmDialog(
                    context,
                    content,
                    confirmText,
                    cancelText,
                    onConfirmClickListener,
                    onCancelClickListener
                )
            )
            .show()
    }

    /**
     * 通用确定弹窗
     */
    fun showCommonDialog(
        context: Context,
        title: String,
        confirmText: String? = null,
        onConfirmListener: ((isBackLive: Boolean) -> Unit),
    ) {
        XPopup.Builder(context)
            .isDestroyOnDismiss(true)
            .asCustom(
                CommonSureDialog(
                    context,
                    title,
                    confirmText,
                    onConfirmListener
                )
            )
            .show()
    }

    /**
     * 显示警告弹窗
     */
    fun showWarningDialog(content: String) {
        val activity = ViewUtils.getAliveTopActivity()
        if (activity != null) {
            val message = PopupWindowMessage(
                title = StringUtils.getString(string.warning),
                content = content,
                payload = "{}",
                confirm = StringUtils.getString(string.confirm)
            )

            XPopup.Builder(activity)
                .hasShadowBg(false)
                .isDestroyOnDismiss(true)
                .asCustom(NormalNoticeDialog(activity, message))
                .show()
        }
    }

    /**
     * 封号账号登录弹窗
     */
    fun showSealAccountDialog(
        context: Context,
        content: String,
    ) {
        XPopup.Builder(context)
            .dismissOnTouchOutside(true)
            .dismissOnBackPressed(true)
            .isDestroyOnDismiss(true)
            .asCustom(SealAccountDialog(context, content))
            .show()
    }

    /**
     * 直播间用户中奖弹窗
     */
    private val mWinningMap = ConcurrentHashMap<String, LiveLuckGiftDialog>()
    fun showUserWinning(
        context: Context,
        payload: InviteGiftPayloadBean,
    ) {
        val time = System.currentTimeMillis()
        val liveLuckGiftDialog = LiveLuckGiftDialog(context, payload, time) {
            if (mWinningMap.containsKey("$it") && mWinningMap["$it"] != null) {
                mWinningMap.remove("$it")
            }
        }
        mWinningMap["$time"] = liveLuckGiftDialog
        XPopup.Builder(context)
            .hasShadowBg(false)
            .isClickThrough(true)
            .isTouchThrough(true)
            .isViewMode(true)
            .isDestroyOnDismiss(true)
            .customAnimator(EmptyAnimator(null, 0))
            .asCustom(liveLuckGiftDialog)
            .show()
    }

    /**
     * 直播间用户中奖弹窗
     */
    private val mBackPackWinningMap = ConcurrentHashMap<String, LiveBackPackLuckGiftDialog>()
    fun showBackPackUserWinning(
        context: Context,
        payload: InviteGiftPayloadBean,
    ) {
        val time = System.currentTimeMillis()
        val liveBackPackLuckGiftDialog = LiveBackPackLuckGiftDialog(context, payload, time) {
            if (mBackPackWinningMap.containsKey("$it") && mBackPackWinningMap["$it"] != null) {
                mBackPackWinningMap.remove("$it")
            }
        }
        mBackPackWinningMap["$time"] = liveBackPackLuckGiftDialog
        XPopup.Builder(context)
            .hasShadowBg(false)
            .isClickThrough(true)
            .isTouchThrough(true)
            .isViewMode(true)
            .isDestroyOnDismiss(true)
            .customAnimator(EmptyAnimator(null, 0))
            .asCustom(liveBackPackLuckGiftDialog)
            .show()
    }

    fun dismissWinningDialog() {
        val keysToRemove = mWinningMap.keys.toList()
        keysToRemove.forEach { key ->
            mWinningMap[key]?.dismiss()
            mWinningMap.remove(key)
        }

        val backKeysToRemove = mBackPackWinningMap.keys.toList()
        backKeysToRemove.forEach { key ->
            mBackPackWinningMap[key]?.dismiss()
            mBackPackWinningMap.remove(key)
        }
    }

    /**
     * 直播间主播通知弹窗
     */
    fun showLiveNotice(
        context: Context,
        sendLiveNoticeMessage: SendLiveNoticeMessage,
    ) {
        if (sendLiveNoticeMessage.type == NOTICE_TYPE_TEXT) {
            XPopup.Builder(context)
                .enableDrag(false)
                .dismissOnTouchOutside(false)
                .isDestroyOnDismiss(true)
                .customAnimator(RechargeAnimator())
                .asCustom(LiveNoticeDialog(context, sendLiveNoticeMessage))
                .show()
        }
    }

    /**
     * 展示新手引导弹窗
     */
    private var mRequstJob: Job? = null
    fun showNewLiving(context: Context, isKeepOnNext: ((mIsClick: Boolean) -> Unit)? = null) {

        mRequstJob = CoroutineScopeManager.mainScope.launch {
            try {
                manualRequest({ liveService.getLiveResource() }, {
                    CommonCache.setLiveResource(it)
//                    if (it.reminderLive == AppConst.YES) {
//                        XPopup.Builder(context)
//                            .setPopupCallback(object : XpopupCallBackImpl {
//                                override fun onDismiss(popupView: BasePopupView) {
//                                    super.onDismiss(popupView)
//                                    mRequstJob?.cancel()
//                                    mRequstJob = null
//                                }
//                            })
//                            .isDestroyOnDismiss(true)
//                            .asCustom(NewLivingGuideDialog(context, isKeepOnNext))
//                            .show()
//                    } else {
//                        isKeepOnNext?.invoke(false)
//                    }
                }, {})
            } finally {
                if (mRequstJob == coroutineContext[Job]) {
                    mRequstJob = null
                }
            }
        }
    }

    /**
     * 直播间主播开播达到时长
     */
    fun showNewLiveAnchor(
        context: Context,
        payload: NewAnchorSubsidyPayloadBean,
    ) {
        XPopup.Builder(context)
            .isDestroyOnDismiss(true)
            .asCustom(NewLiveAnchorDialog(context, payload))
            .show()
    }

    /**
     * 展示游戏规则
     */
    fun showGameRuleDialog(context: Context, rule: String) {
        XPopup.Builder(context)
            .isViewMode(true)
            .hasShadowBg(true)
            .isDestroyOnDismiss(true)
            .asCustom(GameRuleDialog(context, rule))
            .show()
    }

    /**
     * 充值活动-每日领取
     */
    fun showRechargeActivity(
        context: Context,
        viewModel: BaseViewModel,
        block: ((ResultState<List<PayerRechargeDailyRewardsPriceResp>>) -> Unit)? = null,
    ) {
        GlobalViewModelProxy.getRechargeActivity(viewModel) { state ->
            if (state is ResultState.Success) {
                val data = state.data
                val item = data.getOrNull(0) ?: return@getRechargeActivity
                XPopup.Builder(context)
                    .isDestroyOnDismiss(true)
                    .asCustom(RechargeActDialog(context, item, viewModel) {
                        showRechargeActivity(context, viewModel, block)
                    })
                    .show()
            }
        }
    }

    /**
     * 根据送礼物判断是否等级不足
     */
    fun showInsufficientVIPLevel(
        context: Context,
        payload: String?,
        giftPic: String? = null,
        showGoVip: Boolean = true,
    ) {
        payload?.let { pa ->
            val payloadBean = JsonUtils.fromJson<GiftPrivilegePayloadBean>(pa)
            if (payloadBean != null && payloadBean.type == LiveConst.GiftPrivilegeType.VIP) {
                payloadBean.businessId?.let { level ->
                    val hightTips = "VIP$level"
                    OpenVipDialog.show(
                        context,
                        StringUtils.getString(string.decline_an_invitation_is_vip_user_gift, hightTips),
                        level,
                        ImageUtils.imgPath(giftPic),
                        hightTips,
                        showGoVip
                    )
                }
            }

        }
    }
}